#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>

#define NUM 1024
#define SIZE 32 
#define SEP " " //命令行分隔符

//保存完整的命令行字符串
char cmd_line[NUM];
//保存分割后的命令行字符串
char* g_argv[SIZE];
    //shell运行原理：子进程执行命令，父进程等待&&解析命令
int main()
{
   //命令行解释器是一个常驻内存的进程不退出
   while(1)
   {
       //1.打印命令提示符
       printf("[root@LocalHost myshell]# ");
       //fflush(stdout);
       memset(cmd_line,'\0',sizeof(cmd_line));
       
       //2.获取用户的键盘输入信息
       if(fgets(cmd_line,sizeof cmd_line,stdin)==NULL)
       {
           continue;
       }
       //  gets(cmd_line);
       cmd_line[strlen(cmd_line)-1]='\0';
       //printf("%s\n",cmd_line);

       //3.解析命令行信息 "ls -a -l -i" -> "ls" "-a" "-l" "-i"
       //strtok
       g_argv[0]=strtok(cmd_line,SEP);
       int index=1;
       if(strcmp("ls",g_argv[0])==0)
       {
           g_argv[index++]="--color=auto";
       }

       if(strcmp("ll",g_argv[0])==0)
       {
           g_argv[0]="ls";
           g_argv[index++]="-l";
           g_argv[index++]="--color=auto";
       }
       while(g_argv[index++]=strtok(NULL,SEP));
      // int i=0;
      // for(i=0;g_argv[i];i++)
      // {
      //     printf("g_argv[%d]:%s\n",i,g_argv[i]);
      // }
      
       //4.内置命令 让父进程（shell）自己执行的命令，我们叫做内置命令，内建命令
       //内建命令本质其实就是shell中的一个函数调用
       if(strcmp("cd",g_argv[0])==0)
       {
           if(g_argv[1]) chdir(g_argv[1]);
           continue;
       }
      
      //5.fork子进程，执行命令
        pid_t id = fork();
       if(id==0)
       {
           printf("下面是子进程执行的\n");
           execvp(g_argv[0],g_argv);
           exit(1);
       }
       int status=0;
       pid_t ret=waitpid(id,&status,0);
       if(ret>0)
       {
           printf("exit code:%d\n",WEXITSTATUS(status));
       }
   }

    return 0;
}
